home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint;
- /, ÈSid = "$Id: gplt_x11.c,v 1.16.2.4 1999/10/15 16:04:50 lhecking Exp $";
- #endif
-
- /* GNUPLOT - gplt_x11.c */
-
- /*[
- * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the complete modified source code. Modifications are to
- * be distributed as patches to the released version. Permission to
- * distribute binaries produced by compiling modified sources is granted,
- * provided you
- * 1. distribute the corresponding source modifications from the
- * released version in the form of a patch file along with the binaries,
- * 2. add special version identification to distinguish your version
- * in addition to the base release version number,
- * 3. provide your name and address as the primary contact for the
- * support of your modified version, and
- * 4. retain our contact information in regard to use of the base
- * software.
- * Permission to distribute the released version of the source code along
- * with corresponding source modifications in the form of a patch file is
- * granted with same provisions 2 through 4 for binary distributions.
- *
- * This software is provided "as is" without express or implied warranty
- * to the extent permitted by applicable law.
- ]*/
-
-
- /* lph changes:
- * (a) make EXPORT_SELECTION the default and specify NOEXPORT to undefine
- * (b) append X11 terminal number to resource name
- * (c) change cursor for active terminal
- */
-
- /*-----------------------------------------------------------------------------
- * gnuplot_x11 - X11 outboard terminal driver for gnuplot 3.3
- *
- * Requires installation of companion inboard x11 driver in gnuplot/term.c
- *
- * Acknowledgements:
- * Chris Peterson (MIT)
- * Dana Chee (Bellcore)
- * Arthur Smith (Cornell)
- * Hendri Hondorp (University of Twente, The Netherlands)
- * Bill Kucharski (Solbourne)
- * Charlie Kline (University of Illinois)
- * Yehavi Bourvine (Hebrew University of Jerusalem, Israel)
- * Russell Lang (Monash University, Australia)
- * O'Reilly & Associates: X Window System - Volumes 1 & 2
- *
- * This code is provided as is and with no warranties of any kind.
- *
- * drd: change to allow multiple windows to be maintained independently
- *
- * There is a mailing list for gnuplot users. Note, however, that the
- * newsgroup
- * comp.graphics.apps.gnuplot
- * is identical to the mailing list (they
- * both carry the same set of messages). We prefer that you read the
- * messages through that newsgroup, to subscribing to the mailing list.
- * (If you can read that newsgroup, and are already on the mailing list,
- * please send a message to majordomo@dartmouth.edu, asking to be
- * removed from the mailing list.)
- *
- * The address for mailing to list members is
- * info-gnuplot@dartmouth.edu
- * and for mailing administrative requests is
- * majordomo@dartmouth.edu
- * The mailing list for bug reports is
- * bug-gnuplot@dartmouth.edu
- * The list of those interested in beta-test versions is
- * info-gnuplot-beta@dartmouth.edu
- *---------------------------------------------------------------------------*/
-
- /* drd : export the graph via ICCCM primary selection. well... not quite
- * ICCCM since we dont support full list of targets, but this
- * is a start. define EXPORT_SELECTION if you want this feature
- */
-
- /*lph: add a "feature" to undefine EXPORT_SELECTION
- The following makes EXPORT_SELECTION the default and
- defining NOEXPORT over-rides the default
- */
-
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
-
- #ifdef EXPORT_SELECTION
- # undef EXPORT_SELECTION
- #endif /* EXPORT SELECTION */
- #ifndef NOEXPORT
- # define EXPORT_SELECTION XA_PRIMARY
- #endif /* NOEXPORT */
-
-
- #if !(defined(VMS) || defined(CRIPPLED_SELECT))
- # define DEFAULT_X11
- #endif
-
- #if defined(VMS) && defined(CRIPPLED_SELECT)
- Error. Incompatible options.
- #endif
-
-
- #include <X11/Xos.h>
- #include <X11/Xlib.h>
- #include <X11/Xresource.h>
- #include <X11/Xutil.h>
- #include <X11/Xatom.h>
- #include <X11/keysym.h>
-
- #include <signal.h>
-
- #ifdef HAVE_SYS_BSDTYPES_H
- # include <sys/bsdtypes.h>
- #endif /* HAVE_SYS_BSDTYPES_H */
-
- #ifdef __EMX__
- /* for gethostname ... */
- # include <netdb.h>
- #endif
-
- #if defined(HAVE_SYS_SELECT_H) && !defined(VMS)
- # include <sys/select.h>
- #endif /* HAVE_SYS_SELECT_H && !VMS */
-
- #ifndef FD_SET
- # define FD_SET(n, p) ((p)->fds_bits[0] |= (1 << ((n) % 32)))
- # define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1 << ((n) % 32)))
- # define FD_ISSET(n, p) ((p)->fds_bits[0] & (1 << ((n) % 32)))
- # define FD_ZERO(p) memset((char *)(p),'\0',sizeof(*(p)))
- #endif /* not FD_SET */
-
- #include "plot.h"
-
- #if defined(HAVE_SYS_SYSTEMINFO_H) && defined(HAVE_SYSINFO)
- # include <sys/systeminfo.h>
- # define SYSINFO_METHOD "sysinfo"
- # define GP_SYSTEMINFO(host) sysinfo (SI_HOSTNAME, (host), MAXHOSTNAMELEN)
- #else
- # define SYSINFO_METHOD "gethostname"
- # define GP_SYSTEMINFO(host) gethostname ((host), MAXHOSTNAMELEN)
- #endif /* HAVE_SYS_SYSTEMINFO_H && HAVE_SYSINFO */
-
- #ifdef VMS
- # ifdef __DECC
- # include <starlet.h>
- # endif /* __DECC */
- # define EXIT(status) sys$delprc(0,0) /* VMS does not drop itself */
- #else
- # define EXIT(status) exit(status)
- #endif
-
- #ifdef OSK
- # define EINTR E_ILLFNC
- #endif
-
- /* information about one window/plot */
-
- typedef struct plot_struct {
- Window window;
- Pixmap pixmap;
- unsigned int posn_flags;
- int x, y;
- unsigned int width, height; /* window size */
- unsigned int px, py; /* pointsize */
- int ncommands, max_commands;
- char **commands;
- } plot_struct;
-
- void store_command __PROTO((char *line, plot_struct * plot));
- void prepare_plot __PROTO((plot_struct * plot, int term_number));
- void delete_plot __PROTO((plot_struct * plot));
-
- int record __PROTO((void));
- void process_event __PROTO((XEvent * event)); /* from Xserver */
-
- void mainloop __PROTO((void));
-
- void display __PROTO((plot_struct * plot));
-
- void reset_cursor __PROTO((void));
-
- void preset __PROTO((int argc, char *argv[]));
- char *pr_GetR __PROTO((XrmDatabase db, char *resource));
- void pr_color __PROTO((void));
- void pr_dashes __PROTO((void));
- void pr_font __PROTO((void));
- void pr_geometry __PROTO((void));
- void pr_pointsize __PROTO((void));
- void pr_width __PROTO((void));
- Window pr_window __PROTO((unsigned int flags, int x, int y, unsigned int width, unsigned height));
- void pr_raise __PROTO((void));
- void pr_persist __PROTO((void));
-
- #ifdef EXPORT_SELECTION
- void export_graph __PROTO((plot_struct * plot));
- void handle_selection_event __PROTO((XEvent * event));
- #endif
-
- #define FallbackFont "fixed"
-
- #define Ncolors 13
- unsigned long colors[Ncolors];
-
- #define Nwidths 10
- unsigned int widths[Nwidths] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- #define Ndashes 10
- char dashes[Ndashes][5];
-
- #define MAX_WINDOWS 16
-
- #define XC_crosshair 34
-
-
- struct plot_struct plot_array[MAX_WINDOWS];
-
-
- Display *dpy;
- int scr;
- Window root;
- Visual *vis;
- GC gc = (GC) 0;
- XFontStruct *font;
- int do_raise = 1, persist = 0;
- KeyCode q_keycode;
- Cursor cursor;
-
- int windows_open = 0;
-
- int gX = 100, gY = 100;
- unsigned int gW = 640, gH = 450;
- unsigned int gFlags = PSize;
-
- unsigned int BorderWidth = 2;
- unsigned int D; /* depth */
-
- Bool Mono = 0, Gray = 0, Rv = 0, Clear = 0;
- char Name[64] = "gnuplot";
- char Class[64] = "Gnuplot";
-
- int cx = 0, cy = 0, vchar;
- double xscale, yscale, pointsize;
- #define X(x) (int) ((x) * xscale)
- #define Y(y) (int) ((4095-(y)) * yscale)
-
- #define Nbuf 1024
- char buf[Nbuf], **commands = (char **) 0;
- static int buffered_input_available = 0;
-
- FILE *X11_ipc;
- char X11_ipcpath[32];
-
- /* when using an ICCCM-compliant window manager, we can ask it
- * to send us an event when user chooses 'close window'. We do this
- * by setting WM_DELETE_WINDOW atom in property WM_PROTOCOLS
- */
-
- Atom WM_PROTOCOLS, WM_DELETE_WINDOW;
-
- XPoint Diamond[5], Triangle[4];
- XSegment Plus[2], Cross[2], Star[4];
-
- /*-----------------------------------------------------------------------------
- * main program
- *---------------------------------------------------------------------------*/
-
- int
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
-
- #ifdef OSK
- /* malloc large blocks, otherwise problems with fragmented mem */
- _mallocmin(102400);
- #endif
- #ifdef __EMX__
- /* close open file handles */
- fcloseall();
- #endif
-
- FPRINTF((stderr, "gnuplot_X11 starting up\n"));
-
- preset(argc, argv);
-
- /* set up the alternative cursor */
- cursor = XCreateFontCursor(dpy, XC_crosshair);
-
- mainloop();
-
- if (persist) {
- FPRINTF((stderr, "waiting for %d windows\n", windows_open));
- /* read x events until all windows have been quit */
- while (windows_open > 0) {
- XEvent event;
- XNextEvent(dpy, &event);
- process_event(&event);
- }
- }
- XCloseDisplay(dpy);
-
- FPRINTF((stderr, "exiting\n"));
-
- EXIT(0);
- }
-
- /*-----------------------------------------------------------------------------
- * mainloop processing - process X events and input from gnuplot
- *
- * Three different versions of main loop processing are provided to support
- * three different platforms.
- *
- * DEFAULT_X11: use select() for both X events and input on stdin
- * from gnuplot inboard driver
- *
- * CRIPPLED_SELECT: use select() to service X events and check during
- * select timeout for temporary plot file created
- * by inboard driver
- *
- * VMS: use XNextEvent to service X events and AST to
- * service input from gnuplot inboard driver on stdin
- *---------------------------------------------------------------------------*/
-
-
- #ifdef DEFAULT_X11
- /*-----------------------------------------------------------------------------
- * DEFAULT_X11 mainloop
- *---------------------------------------------------------------------------*/
-
- void
- mainloop()
- {
- int nf, cn = ConnectionNumber(dpy), in;
- fd_set_size_t nfds;
- struct timeval timeout, *timer = (struct timeval *) 0;
- fd_set tset;
-
- X11_ipc = stdin;
- in = fileno(X11_ipc);
-
- #ifdef ISC22
- /* Added by Robert Eckardt, RobertE@beta.TP2.Ruhr-Uni-Bochum.de */
- timeout.tv_sec = 0; /* select() in ISC2.2 needs timeout */
- timeout.tv_usec = 300000; /* otherwise input from gnuplot is */
- timer = &timeout; /* suspended til next X event. */
- #endif /* ISC22 (0.3s are short enough not to be noticed */
-
- while (1) {
-
- /* XNextEvent does an XFlush() before waiting. But here.
- * we must ensure that the queue is flushed, since we
- * dont call XNextEvent until an event arrives. (I have
- * twice wasted quite some time over this issue, so now
- * I am making sure of it !
- */
-
- XFlush(dpy);
-
- FD_ZERO(&tset);
- FD_SET(cn, &tset);
-
- /* Don't wait for events if we know that input is
- * already sitting in a buffer. Also don't wait for
- * input to become available.
- */
- if (buffered_input_available) {
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- timer = &timeout;
- } else {
- timer = (struct timeval *) 0;
- FD_SET(in, &tset);
- }
-
- nfds = (cn > in) ? cn + 1 : in + 1;
-
- nf = select(nfds, SELECT_FD_SET_CAST &tset, 0, 0, timer);
-
- if (nf < 0) {
- if (errno == EINTR)
- continue;
- fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
- EXIT(1);
- }
-
- if (nf > 0)
- XNoOp(dpy);
-
- if (FD_ISSET(cn, &tset)) {
- /* used to use CheckMaskEvent() but that cannot receive
- * maskable events such as ClientMessage. So now we do
- * one event, then return to the select.
- * And that almost works, except that under some Xservers
- * running without a window manager (e.g. Hummingbird Exceed under Win95)
- * a bogus ConfigureNotify is sent followed by a valid ConfigureNotify
- * when the window is maximized. The two events are queued, apparently
- * in a single I/O because select() above doesn't see the second, valid
- * event. This little loop fixes the problem by flushing the
- * event queue completely.
- */
- XEvent xe;
- do {
- XNextEvent(dpy, &xe);
- process_event(&xe);
- } while (XPending(dpy));
- }
-
- if (FD_ISSET(in, &tset) || buffered_input_available) {
- if (!record()) /* end of input */
- return;
- }
- }
- }
-
-
- #elif defined(CRIPPLED_SELECT)
- /*-----------------------------------------------------------------------------
- * CRIPPLED_SELECT mainloop
- *---------------------------------------------------------------------------*/
-
- void
- mainloop()
- {
- fd_set_size_t nf, nfds, cn = ConnectionNumber(dpy);
- struct timeval timeout, *timer;
- fd_set tset;
- unsigned long all = (unsigned long) (-1L);
- XEvent xe;
-
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- timer = &timeout;
- sprintf(X11_ipcpath, "/tmp/Gnuplot_%d", getppid());
- nfds = cn + 1;
-
- while (1) {
- XFlush(dpy); /* see above */
-
- FD_ZERO(&tset);
- FD_SET(cn, &tset);
-
- /* Don't wait for events if we know that input is
- * already sitting in a buffer. Also don't wait for
- * input to become available.
- */
- if (buffered_input_available) {
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- timer = &timeout;
- } else {
- timer = (struct timeval *) 0;
- FD_SET(in, &tset);
- }
-
- nfds = (cn > in) ? cn + 1 : in + 1;
-
- nf = select(nfds, SELECT_FD_SET_CAST &tset, 0, 0, timer);
-
- if (nf < 0) {
- if (errno == EINTR)
- continue;
- fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
- EXIT(1);
- }
-
- if (nf > 0)
- XNoOp(dpy);
-
- if (FD_ISSET(cn, &tset)) {
- while (XCheckMaskEvent(dpy, all, &xe)) {
- process_event(&xe);
- }
- }
- if ((X11_ipc = fopen(X11_ipcpath, "r"))) {
- unlink(X11_ipcpath);
- record();
- fclose(X11_ipc);
- }
- }
- }
-
-
- #elif defined(VMS)
- /*-----------------------------------------------------------------------------
- * VMS mainloop - Yehavi Bourvine - YEHAVI@VMS.HUJI.AC.IL
- *---------------------------------------------------------------------------*/
-
- /* In VMS there is no decent Select(). hence, we have to loop inside
- * XGetNextEvent for getting the next X window event. In order to get input
- * from the master we assign a channel to SYS$INPUT and use AST's in order to
- * receive data. In order to exit the mainloop, we need to somehow make
- * XNextEvent return from within the ast. We do this with a XSendEvent() to
- * ourselves !
- * This needs a window to send the message to, so we create an unmapped window
- * for this purpose. Event type XClientMessage is perfect for this, but it
- * appears that such messages come from elsewhere (motif window manager,
- * perhaps ?) So we need to check fairly carefully that it is the ast event
- * that has been received.
- */
-
- #include <iodef.h>
- char STDIIN[] = "SYS$INPUT:";
- short STDIINchannel, STDIINiosb[4];
- struct {
- short size, type;
- char *address;
- } STDIINdesc;
- char STDIINbuffer[64];
- int status;
-
- ast()
- {
- int status = sys$qio(0, STDIINchannel, IO$_READVBLK, STDIINiosb, record,
- 0, STDIINbuffer, sizeof(STDIINbuffer) - 1, 0, 0, 0, 0);
- if ((status & 0x1) == 0)
- EXIT(status);
- }
-
- Window message_window;
-
- void
- mainloop()
- {
- /* dummy unmapped window for receiving internally-generated terminate
- * messages
- */
- message_window = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 1, 0, 0);
-
- STDIINdesc.size = strlen(STDIIN);
- STDIINdesc.type = 0;
- STDIINdesc.address = STDIIN;
- status = sys$assign(&STDIINdesc, &STDIINchannel, 0, 0, 0);
- if ((status & 0x1) == 0)
- EXIT(status);
- ast();
-
- for (;;) {
- XEvent xe;
- XNextEvent(dpy, &xe);
- if (xe.type == ClientMessage && xe.xclient.window == message_window) {
- if (xe.xclient.message_type == None &&
- xe.xclient.format == 8 &&
- strcmp(xe.xclient.data.b, "die gnuplot die") == 0) {
- FPRINTF((stderr, "quit message from ast\n"));
- return;
- } else {
- FPRINTF((stderr, "Bogus XClientMessage event from window manager ?\n"));
- }
- }
- process_event(&xe);
- }
- }
- #else /* !(DEFAULT_X11 || CRIPPLED_SELECT || VMS */
- You lose. No mainloop.
- #endif /* !(DEFAULT_X11 || CRIPPLED_SELECT || VMS */
-
- /* delete a window / plot */
-
- void
- delete_plot(plot)
- plot_struct *plot;
- {
- int i;
-
- FPRINTF((stderr, "Delete plot %d\n", plot - plot_array));
-
- for (i = 0; i < plot->ncommands; ++i)
- free(plot->commands[i]);
- plot->ncommands = 0;
-
- if (plot->window) {
- FPRINTF((stderr, "Destroy window 0x%x\n", plot->window));
- XDestroyWindow(dpy, plot->window);
- plot->window = None;
- --windows_open;
- }
- if (plot->pixmap) {
- XFreePixmap(dpy, plot->pixmap);
- plot->pixmap = None;
- }
- /* but preserve geometry */
- }
-
-
- /* prepare the plot structure */
-
- void
- prepare_plot(plot, term_number)
- plot_struct *plot;
- int term_number;
- {
- int i;
- char *term_name;
-
- for (i = 0; i < plot->ncommands; ++i)
- free(plot->commands[i]);
- plot->ncommands = 0;
-
- if (!plot->posn_flags) {
- /* first time this window has been used - use default or -geometry
- * settings
- */
- plot->posn_flags = gFlags;
- plot->x = gX;
- plot->y = gY;
- plot->width = gW;
- plot->height = gH;
- }
- if (!plot->window) {
- plot->window = pr_window(plot->posn_flags, plot->x, plot->y, plot->width, plot->height);
- ++windows_open;
-
- /* append the X11 terminal number (if greater than zero) */
-
- if (term_number) {
- char new_name[60];
- XFetchName(dpy, plot->window, &term_name);
- FPRINTF((stderr, "Window title is %s\n", term_name));
-
- sprintf(new_name, "%.55s%3d", term_name, term_number);
- FPRINTF((stderr, "term_number is %d\n", term_number));
-
- XStoreName(dpy, plot->window, new_name);
-
- sprintf(new_name, "gplt%3d", term_number);
- XSetIconName(dpy, plot->window, new_name);
- }
- }
- /* We don't know that it is the same window as before, so we reset the
- * cursors for all windows and then define the cursor for the active
- * window
- */
- reset_cursor();
- XDefineCursor(dpy, plot->window, cursor);
-
- }
-
- /* store a command in a plot structure */
-
- void
- store_command(buffer, plot)
- char *buffer;
- plot_struct *plot;
- {
- char *p;
-
- FPRINTF((stderr, "Store in %d : %s", plot - plot_array, buffer));
-
- if (plot->ncommands >= plot->max_commands) {
- plot->max_commands = plot->max_commands * 2 + 1;
- plot->commands = (plot->commands)
- ? (char **) realloc(plot->commands, plot->max_commands * sizeof(char *))
- : (char **) malloc(sizeof(char *));
- }
- p = (char *) malloc((unsigned) strlen(buffer) + 1);
- if (!plot->commands || !p) {
- fputs("gnuplot: can't get memory. X11 aborted.\n", stderr);
- EXIT(1);
- }
- plot->commands[plot->ncommands++] = strcpy(p, buffer);
- }
-
- #ifndef VMS
-
- /* Handle input. Use read instead of fgets because stdio buffering
- * causes trouble when combined with calls to select.
- */
- int
- read_input ()
- {
- static int rdbuf_size = 10*Nbuf;
- static char rdbuf[10*Nbuf-1];
- static int total_chars;
- static int rdbuf_offset;
- static int buf_offset;
- static int partial_read = 0;
- int fd = fileno (X11_ipc);
-
- if (! partial_read)
- buf_offset = 0;
-
- if (! buffered_input_available) {
- total_chars = read (fd, rdbuf, rdbuf_size);
- buffered_input_available = 1;
- partial_read = 0;
- rdbuf_offset = 0;
- if (total_chars < 0)
- return -1;
- }
-
- if (rdbuf_offset < total_chars) {
- while (rdbuf_offset < total_chars && buf_offset < Nbuf) {
- char c = rdbuf[rdbuf_offset++];
- buf[buf_offset++] = c;
- if (c == '\n')
- break;
- }
-
- if (buf_offset == Nbuf) {
- fputs("\
- \n\
- gnuplot: buffer overflow in read_input!\n\
- gnuplot: X11 aborted.\n", stderr);
- EXIT(1);
- } else
- buf[buf_offset] = NUL;
- }
-
- if (rdbuf_offset == total_chars) {
- buffered_input_available = 0;
- if (buf[buf_offset-1] != '\n')
- partial_read = 1;
- }
-
- return partial_read;
- }
-
-
- /*-----------------------------------------------------------------------------
- * record - record new plot from gnuplot inboard X11 driver (Unix)
- *---------------------------------------------------------------------------*/
-
- int
- record()
- {
- static plot_struct *plot = plot_array;
-
- while (1) {
- int status = read_input ();
- if (status != 0)
- return status;
-
- switch (*buf) {
- case 'G': /* enter graphics mode */
- {
- int plot_number = atoi(buf + 1); /* 0 if none specified */
-
- if (plot_number < 0 || plot_number >= MAX_WINDOWS)
- plot_number = 0;
-
- FPRINTF((stderr, "plot for window number %d\n", plot_number));
- plot = plot_array + plot_number;
- prepare_plot(plot, plot_number);
- continue;
- }
- case 'E': /* leave graphics mode / suspend */
- display(plot);
- return 1;
- case 'R': /* leave x11 mode */
- reset_cursor();
- return 0;
- default:
- store_command(buf, plot);
- continue;
- }
- }
- }
-
- #else /* VMS */
- /*-----------------------------------------------------------------------------
- * record - record new plot from gnuplot inboard X11 driver (VMS)
- *---------------------------------------------------------------------------*/
-
- record()
- {
- static plot_struct *plot = plot_array;
-
- int status;
-
- if ((STDIINiosb[0] & 0x1) == 0)
- EXIT(STDIINiosb[0]);
- STDIINbuffer[STDIINiosb[1]] = '\0';
- strcpy(buf, STDIINbuffer);
-
- switch (*buf) {
- case 'G': /* enter graphics mode */
- {
- int plot_number = atoi(buf + 1); /* 0 if none specified */
- if (plot_number < 0 || plot_number >= MAX_WINDOWS)
- plot_number = 0;
- FPRINTF((stderr, "plot for window number %d\n", plot_number));
- plot = plot_array + plot_number;
- prepare_plot(plot, plot_number);
- break;
- }
- case 'E': /* leave graphics mode */
- display(plot);
- break;
- case 'R': /* exit x11 mode */
- FPRINTF((stderr, "received R - sending ClientMessage\n"));
- reset_cursor();
- sys$cancel(STDIINchannel);
- /* this is ridiculous - cook up an event to ourselves,
- * in order to get the mainloop() out of the XNextEvent() call
- * it seems that window manager can also send clientmessages,
- * so put a checksum into the message
- */
- {
- XClientMessageEvent event;
- event.type = ClientMessage;
- event.send_event = True;
- event.display = dpy;
- event.window = message_window;
- event.message_type = None;
- event.format = 8;
- strcpy(event.data.b, "die gnuplot die");
- XSendEvent(dpy, message_window, False, 0, (XEvent *) & event);
- XFlush(dpy);
- }
- return; /* no ast */
- default:
- store_command(buf, plot);
- break;
- }
- ast();
- }
- #endif /* VMS */
-
-
- /*-----------------------------------------------------------------------------
- * display - display a stored plot
- *---------------------------------------------------------------------------*/
-
- void
- display(plot)
- plot_struct *plot;
- {
- int n, x, y, sw, sl, lt = 0, width, type, point, px, py;
- int user_width = 1; /* as specified by plot...linewidth */
- char *buffer, *str;
- enum JUSTIFY jmode;
-
- FPRINTF((stderr, "Display %d ; %d commands\n", plot - plot_array, plot->ncommands));
-
- if (plot->ncommands == 0)
- return;
-
- /* set scaling factor between internal driver & window geometry */
- xscale = plot->width / 4096.0;
- yscale = plot->height / 4096.0;
-
- /* initial point sizes, until overridden with P7xxxxyyyy */
- px = (int) (xscale * pointsize);
- py = (int) (yscale * pointsize);
-
- /* create new pixmap & GC */
- if (gc)
- XFreeGC(dpy, gc);
-
- if (!plot->pixmap) {
- FPRINTF((stderr, "Create pixmap %d : %dx%dx%d\n", plot - plot_array, plot->width,
- plot->height, D));
- plot->pixmap = XCreatePixmap(dpy, root, plot->width, plot->height, D);
- }
- gc = XCreateGC(dpy, plot->pixmap, 0, (XGCValues *) 0);
-
- XSetFont(dpy, gc, font->fid);
-
- /* set pixmap background */
- XSetForeground(dpy, gc, colors[0]);
- XFillRectangle(dpy, plot->pixmap, gc, 0, 0, plot->width, plot->height);
- XSetBackground(dpy, gc, colors[0]);
-
- if (!plot->window) {
- plot->window = pr_window(plot->posn_flags, plot->x, plot->y, plot->width, plot->height);
- ++windows_open;
- }
- /* top the window but don't put keyboard or mouse focus into it. */
- if (do_raise)
- XMapRaised(dpy, plot->window);
-
- /* momentarily clear the window first if requested */
- if (Clear) {
- XClearWindow(dpy, plot->window);
- XFlush(dpy);
- }
- /* loop over accumulated commands from inboard driver */
- for (n = 0; n < plot->ncommands; n++) {
- buffer = plot->commands[n];
-
- /* X11_vector(x,y) - draw vector */
- if (*buffer == 'V') {
- sscanf(buffer, "V%4d%4d", &x, &y);
- XDrawLine(dpy, plot->pixmap, gc, X(cx), Y(cy), X(x), Y(y));
- cx = x;
- cy = y;
- }
- /* X11_move(x,y) - move */
- else if (*buffer == 'M')
- sscanf(buffer, "M%4d%4d", &cx, &cy);
-
- /* X11_put_text(x,y,str) - draw text */
- else if (*buffer == 'T') {
- sscanf(buffer, "T%4d%4d", &x, &y);
- str = buffer + 9;
- sl = strlen(str) - 1;
- sw = XTextWidth(font, str, sl);
-
- switch (jmode) {
- case LEFT:
- sw = 0;
- break;
- case CENTRE:
- sw = -sw / 2;
- break;
- case RIGHT:
- sw = -sw;
- break;
- }
-
- XSetForeground(dpy, gc, colors[2]);
- XDrawString(dpy, plot->pixmap, gc, X(x) + sw, Y(y) + vchar / 3, str, sl);
- XSetForeground(dpy, gc, colors[lt + 3]);
- } else if (*buffer == 'F') { /* fill box */
- int style, xtmp, ytmp, w, h;
-
- if (sscanf(buffer + 1, "%4d%4d%4d%4d%4d", &style, &xtmp, &ytmp, &w, &h) == 5) {
- /* gnuplot has origin at bottom left, but X uses top left
- * There may be an off-by-one (or more) error here.
- * style ignored here for the moment
- */
- ytmp += h; /* top left corner of rectangle to be filled */
- w *= xscale;
- h *= yscale;
- XSetForeground(dpy, gc, colors[0]);
- XFillRectangle(dpy, plot->pixmap, gc, X(xtmp), Y(ytmp), w, h);
- XSetForeground(dpy, gc, colors[lt + 3]);
- }
- }
- /* X11_justify_text(mode) - set text justification mode */
- else if (*buffer == 'J')
- sscanf(buffer, "J%4d", (int *) &jmode);
-
- /* X11_linewidth(width) - set line width */
- else if (*buffer == 'W')
- sscanf(buffer + 1, "%4d", &user_width);
-
- /* X11_linetype(type) - set line type */
- else if (*buffer == 'L') {
- sscanf(buffer, "L%4d", <);
- lt = (lt % 8) + 2;
- /* default width is 0 {which X treats as 1} */
- width = widths[lt] ? user_width * widths[lt] : user_width;
- if (dashes[lt][0]) {
- type = LineOnOffDash;
- XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
- } else {
- type = LineSolid;
- }
- XSetForeground(dpy, gc, colors[lt + 3]);
- XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
- }
- /* X11_point(number) - draw a point */
- else if (*buffer == 'P') {
- /* linux sscanf does not like %1d%4d%4d" with Oxxxxyyyy */
- /* sscanf(buffer, "P%1d%4d%4d", &point, &x, &y); */
- point = buffer[1] - '0';
- sscanf(buffer + 2, "%4d%4d", &x, &y);
- if (point == 7) {
- /* set point size */
- px = (int) (x * xscale * pointsize);
- py = (int) (y * yscale * pointsize);
- } else {
- if (type != LineSolid || width != 0) { /* select solid line */
- XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinBevel);
- }
- switch (point) {
- case 0: /* dot */
- XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
- break;
- case 1: /* do diamond */
- Diamond[0].x = (short) X(x) - px;
- Diamond[0].y = (short) Y(y);
- Diamond[1].x = (short) px;
- Diamond[1].y = (short) -py;
- Diamond[2].x = (short) px;
- Diamond[2].y = (short) py;
- Diamond[3].x = (short) -px;
- Diamond[3].y = (short) py;
- Diamond[4].x = (short) -px;
- Diamond[4].y = (short) -py;
-
- /*
- * Should really do a check with XMaxRequestSize()
- */
- XDrawLines(dpy, plot->pixmap, gc, Diamond, 5, CoordModePrevious);
- XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
- break;
- case 2: /* do plus */
- Plus[0].x1 = (short) X(x) - px;
- Plus[0].y1 = (short) Y(y);
- Plus[0].x2 = (short) X(x) + px;
- Plus[0].y2 = (short) Y(y);
- Plus[1].x1 = (short) X(x);
- Plus[1].y1 = (short) Y(y) - py;
- Plus[1].x2 = (short) X(x);
- Plus[1].y2 = (short) Y(y) + py;
-
- XDrawSegments(dpy, plot->pixmap, gc, Plus, 2);
- break;
- case 3: /* do box */
- XDrawRectangle(dpy, plot->pixmap, gc, X(x) - px, Y(y) - py, (px + px), (py + py));
- XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
- break;
- case 4: /* do X */
- Cross[0].x1 = (short) X(x) - px;
- Cross[0].y1 = (short) Y(y) - py;
- Cross[0].x2 = (short) X(x) + px;
- Cross[0].y2 = (short) Y(y) + py;
- Cross[1].x1 = (short) X(x) - px;
- Cross[1].y1 = (short) Y(y) + py;
- Cross[1].x2 = (short) X(x) + px;
- Cross[1].y2 = (short) Y(y) - py;
-
- XDrawSegments(dpy, plot->pixmap, gc, Cross, 2);
- break;
- case 5: /* do triangle */
- {
- short temp_x, temp_y;
-
- temp_x = (short) (1.33 * (double) px + 0.5);
- temp_y = (short) (1.33 * (double) py + 0.5);
-
- Triangle[0].x = (short) X(x);
- Triangle[0].y = (short) Y(y) - temp_y;
- Triangle[1].x = (short) temp_x;
- Triangle[1].y = (short) 2 *py;
- Triangle[2].x = (short) -(2 * temp_x);
- Triangle[2].y = (short) 0;
- Triangle[3].x = (short) temp_x;
- Triangle[3].y = (short) -(2 * py);
-
- XDrawLines(dpy, plot->pixmap, gc, Triangle, 4, CoordModePrevious);
- XDrawPoint(dpy, plot->pixmap, gc, X(x), Y(y));
- }
- break;
- case 6: /* do star */
- Star[0].x1 = (short) X(x) - px;
- Star[0].y1 = (short) Y(y);
- Star[0].x2 = (short) X(x) + px;
- Star[0].y2 = (short) Y(y);
- Star[1].x1 = (short) X(x);
- Star[1].y1 = (short) Y(y) - py;
- Star[1].x2 = (short) X(x);
- Star[1].y2 = (short) Y(y) + py;
- Star[2].x1 = (short) X(x) - px;
- Star[2].y1 = (short) Y(y) - py;
- Star[2].x2 = (short) X(x) + px;
- Star[2].y2 = (short) Y(y) + py;
- Star[3].x1 = (short) X(x) - px;
- Star[3].y1 = (short) Y(y) + py;
- Star[3].x2 = (short) X(x) + px;
- Star[3].y2 = (short) Y(y) - py;
-
- XDrawSegments(dpy, plot->pixmap, gc, Star, 4);
- break;
- }
- if (type != LineSolid || width != 0) { /* select solid line */
- XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
- }
- }
- }
- }
-
- /* set new pixmap as window background */
- XSetWindowBackgroundPixmap(dpy, plot->window, plot->pixmap);
-
- /* trigger exposure of background pixmap */
- XClearWindow(dpy, plot->window);
-
- #ifdef EXPORT_SELECTION
- export_graph(plot);
- #endif
-
- XFlush(dpy);
- }
-
- /*---------------------------------------------------------------------------
- * reset all cursors (since we dont have a record of the previous terminal #)
- *---------------------------------------------------------------------------*/
-
- void
- reset_cursor()
- {
- int plot_number;
- plot_struct *plot = plot_array;
-
- for (plot_number = 0, plot = plot_array;
- plot_number < MAX_WINDOWS;
- ++plot_number, ++plot) {
- if (plot->window) {
- FPRINTF((stderr, "Window for plot %d exists\n", plot_number));
- XUndefineCursor(dpy, plot->window);;
- }
- }
-
- FPRINTF((stderr, "Cursors reset\n"));
- return;
- }
-
- /*-----------------------------------------------------------------------------
- * resize - rescale last plot if window resized
- *---------------------------------------------------------------------------*/
-
- plot_struct *
- find_plot(window)
- Window window;
- {
- int plot_number;
- plot_struct *plot = plot_array;
-
- for (plot_number = 0, plot = plot_array;
- plot_number < MAX_WINDOWS;
- ++plot_number, ++plot) {
- if (plot->window == window) {
- FPRINTF((stderr, "Event for plot %d\n", plot_number));
- return plot;
- }
- }
-
- FPRINTF((stderr, "Bogus window 0x%x in event !\n", window));
- return NULL;
- }
-
- void
- process_event(event)
- XEvent *event;
- {
- FPRINTF((stderr, "Event 0x%x\n", event->type));
-
- switch (event->type) {
- case ConfigureNotify:
- {
- plot_struct *plot = find_plot(event->xconfigure.window);
- if (plot) {
- int w = event->xconfigure.width, h = event->xconfigure.height;
-
- /* store settings in case window is closed then recreated */
- plot->x = event->xconfigure.x;
- plot->y = event->xconfigure.y;
- plot->posn_flags = (plot->posn_flags & ~PPosition) | USPosition;
-
- if (w > 1 && h > 1 && (w != plot->width || h != plot->height)) {
- plot->width = w;
- plot->height = h;
- plot->posn_flags = (plot->posn_flags & ~PSize) | USSize;
- if (plot->pixmap) {
- /* it is the wrong size now */
- FPRINTF((stderr, "Free pixmap %d\n", 0));
- XFreePixmap(dpy, plot->pixmap);
- plot->pixmap = None;
- }
- display(plot);
- }
- }
- break;
- }
- case KeyPress:
- if (event->xkey.keycode == q_keycode) {
- plot_struct *plot = find_plot(event->xkey.win}Ò}Ó}Ô}Õ}Ö}×}Ø}Ùlot)
- delete_plot(plot);
- }
- break;
- case ClientMessage:
- if (event->xclient.message_type == WM_PROTOCOLS &&
- event->xclient.format == 32 &&
- event->xclient.data.l[0] == WM_DELETE_WINDOW) {
- plot_struct *plot = find_plot(event->xclient.window);
- if (plot)
- delete_plot(plot);
- }
- break;
- #ifdef EXPORT_SELECTION
- case SelectionNotify:
- case SelectionRequest:
- handle_selection_event(event);
- break;
- #endif
- }
- }
-
- /*-----------------------------------------------------------------------------
- * preset - determine options, open display, create window
- *---------------------------------------------------------------------------*/
- /*
- #define On(v) ( !strcmp(v,"on") || !strcmp(v,"true") || \
- !strcmp(v,"On") || !strcmp(v,"True") || \
- !strcmp(v,"ON") || !strcmp(v,"TRUE") )
- */
- #define On(v) ( !strnicmp(v,"on",2) || !strnicmp(v,"true",4) )
-
- #define AppDefDir "/usr/lib/X11/app-defaults"
- #ifndef MAXHOSTNAMELEN
- #define MAXHOSTNAMELEN 64
- #endif
-
- static XrmDatabase dbCmd, dbApp, dbDef, dbEnv, db = (XrmDatabase) 0;
-
- char *pr_GetR(), *getenv(), *type[20];
- XrmValue value;
-
- static XrmOptionDescRec options[] = {
- {"-mono", ".mono", XrmoptionNoArg, (caddr_t) "on"},
- {"-gray", ".gray", XrmoptionNoArg, (caddr_t) "on"},
- {"-clear", ".clear", XrmoptionNoArg, (caddr_t) "on"},
- {"-tvtwm", ".tvtwm", XrmoptionNoArg, (caddr_t) "on"},
- {"-pointsize", ".pointsize", XrmoptionSepArg, (caddr_t) NULL},
- {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
- {"-name", ".name", XrmoptionSepArg, (caddr_t) NULL},
- {"-geometry", "*geometry", XrmoptionSepArg, (caddr_t) NULL},
- {"-background", "*background", XrmoptionSepArg, (caddr_t) NULL},
- {"-bg", "*background", XrmoptionSepArg, (caddr_t) NULL},
- {"-foreground", "*foreground", XrmoptionSepArg, (caddr_t) NULL},
- {"-fg", "*foreground", XrmoptionSepArg, (caddr_t) NULL},
- {"-bordercolor", "*bordercolor", XrmoptionSepArg, (caddr_t) NULL},
- {"-bd", "*bordercolor", XrmoptionSepArg, (caddr_t) NULL},
- {"-borderwidth", ".borderwidth", XrmoptionSepArg, (caddr_t) NULL},
- {"-bw", ".borderwidth", XrmoptionSepArg, (caddr_t) NULL},
- {"-font", "*font", XrmoptionSepArg, (caddr_t) NULL},
- {"-fn", "*font", XrmoptionSepArg, (caddr_t) NULL},
- {"-reverse", "*reverseVideo", XrmoptionNoArg, (caddr_t) "on"},
- {"-rv", "*reverseVideo", XrmoptionNoArg, (caddr_t) "on"},
- {"+rv", "*reverseVideo", XrmoptionNoArg, (caddr_t) "off"},
- {"-iconic", "*iconic", XrmoptionNoArg, (caddr_t) "on"},
- {"-synchronous", "*synchronous", XrmoptionNoArg, (caddr_t) "on"},
- {"-xnllanguage", "*xnllanguage", XrmoptionSepArg, (caddr_t) NULL},
- {"-selectionTimeout", "*selectionTimeout", XrmoptionSepArg, (caddr_t) NULL},
- {"-title", ".title", XrmoptionSepArg, (caddr_t) NULL},
- {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL},
- {"-raise", "*raise", XrmoptionNoArg, (caddr_t) "on"},
- {"-noraise", "*raise", XrmoptionNoArg, (caddr_t) "off"},
- {"-persist", "*persist", XrmoptionNoArg, (caddr_t) "on"}
- };
-
- #define Nopt (sizeof(options) / sizeof(options[0]))
-
- void
- preset(argc, argv)
- int argc;
- char *argv[];
- {
- int Argc = argc;
- char **Argv = argv;
-
- #ifdef VMS
- char *ldisplay = (char *) 0;
- #else
- char *ldisplay = getenv("DISPLAY");
- #endif
- char *home = getenv("HOME");
- char *server_defaults, *env, buffer[256];
-
- /* avoid bus error when env vars are not set */
- if (ldisplay == NULL)
- ldisplay = "";
- if (home == NULL)
- home = "";
-
- /*---set to ignore ^C and ^Z----------------------------------------------*/
-
- signal(SIGINT, SIG_IGN);
- #ifdef SIGTSTP
- signal(SIGTSTP, SIG_IGN);
- #endif
-
- /*---prescan arguments for "-name"----------------------------------------*/
-
- while (++Argv, --Argc > 0) {
- if (!strcmp(*Argv, "-name") && Argc > 1) {
- strncpy(Name, Argv[1], sizeof(Name) - 1);
- strncpy(Class, Argv[1], sizeof(Class) - 1);
- /* just in case */
- Name[sizeof(Name)-1] = NUL;
- Class[sizeof(Class)-1] = NUL;
- if (Class[0] >= 'a' && Class[0] <= 'z')
- Class[0] -= 0x20;
- }
- }
- Argc = argc;
- Argv = argv;
-
- /*---parse command line---------------------------------------------------*/
-
- XrmInitialize();
- XrmParseCommand(&dbCmd, options, Nopt, Name, &Argc, Argv);
- if (Argc > 1) {
- fprintf(stderr, "\n\
- gnuplot: bad option: %s\n\
- gnuplot: X11 aborted.\n", Argv[1]);
- EXIT(1);
- }
- if (pr_GetR(dbCmd, ".display"))
- ldisplay = (char *) value.addr;
-
- /*---open display---------------------------------------------------------*/
-
- dpy = XOpenDisplay(ldisplay);
- if (!dpy) {
- fprintf(stderr, "\n\
- gnuplot: unable to open display '%s'\n\
- gnuplot: X11 aborted.\n", ldisplay);
- EXIT(1);
- }
- scr = DefaultScreen(dpy);
- vis = DefaultVisual(dpy, scr);
- D = DefaultDepth(dpy, scr);
- root = DefaultRootWindow(dpy);
- server_defaults = XResourceManagerString(dpy);
-
- /*---get symcode for key q ---*/
-
- q_keycode = XKeysymToKeycode(dpy, XK_q);
-
- /**** atoms we will need later ****/
-
- WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
- WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-
-
- /*---get application defaults--(subset of Xt processing)------------------*/
-
- #ifdef VMS
- strcpy(buffer, "DECW$USER_DEFAULTS:GNUPLOT_X11.INI");
- #elif defined OS2
- /* for Xfree86 ... */
- {
- char *appdefdir = "XFree86/lib/X11/app-defaults";
- char *xroot = getenv("X11ROOT");
- sprintf(buffer, "%s/%s/%s", xroot, appdefdir, "Gnuplot");
- }
- # else /* !OS/2 */
- strcpy(buffer, AppDefDir);
- strcat(buffer, "/");
- strcat(buffer, "Gnuplot");
- #endif /* !VMS */
-
- dbApp = XrmGetFileDatabase(buffer);
- XrmMergeDatabases(dbApp, &db);
-
- /*---get server or ~/.Xdefaults-------------------------------------------*/
-
- if (server_defaults)
- dbDef = XrmGetStringDatabase(server_defaults);
- else {
- #ifdef VMS
- strcpy(buffer, "DECW$USER_DEFAULTS:DECW$XDEFAULTS.DAT");
- #else
- strcpy(buffer, home);
- strcat(buffer, ".Xdefaults");
- #endif
- dbDef = XrmGetFileDatabase(buffer);
- }
- XrmMergeDatabases(dbDef, &db);
-
- /*---get XENVIRONMENT or ~/.Xdefaults-hostname---------------------------*/
-
- #ifndef VMS
- if ((env = getenv("XENVIRONMENT")) != NULL)
- dbEnv = XrmGetFileDatabase(env);
- else {
- char *p = NULL, host[MAXHOSTNAMELEN];
-
- if (GP_SYSTEMINFO(host) < 0) {
- fprintf(stderr, "gnuplot: %s failed. X11 aborted.\n", SYSINFO_METHOD);
- EXIT(1);
- }
- if ((p = strchr(host, '.')) != NULL)
- *p = '\0';
- strcpy(buffer, home);
- strcat(buffer, "/.Xdefaults-");
- strcat(buffer, host);
- dbEnv = XrmGetFileDatabase(buffer);
- }
- XrmMergeDatabases(dbEnv, &db);
- #endif /* not VMS */
-
- /*---merge command line options-------------------------------------------*/
-
- XrmMergeDatabases(dbCmd, &db);
-
- /*---set geometry, font, colors, line widths, dash styles, point size-----*/
-
- pr_geometry();
- pr_font();
- pr_color();
- pr_width();
- pr_dashes();
- pr_pointsize();
- pr_raise();
- pr_persist();
- }
-
- /*-----------------------------------------------------------------------------
- * pr_GetR - get resource from database using "-name" option (if any)
- *---------------------------------------------------------------------------*/
-
- char *
- pr_GetR(xrdb, resource)
- XrmDatabase xrdb;
- char *resource;
- {
- char name[128], class[128], *rc;
-
- strcpy(name, Name);
- strcat(name, resource);
- strcpy(class, Class);
- strcat(class, resource);
- rc = XrmGetResource(xrdb, name, class, type, &value)
- ? (char *) value.addr
- : (char *) 0;
- return (rc);
- }
-
- /*-----------------------------------------------------------------------------
- * pr_color - determine color values
- *---------------------------------------------------------------------------*/
-
- char color_keys[Ncolors][30] = {
- "background", "bordercolor", "text", "border", "axis",
- "line1", "line2", "line3", "line4",
- "line5", "line6", "line7", "line8"
- };
- char color_values[Ncolors][30] = {
- "white", "black", "black", "black", "black",
- "red", "green", "blue", "magenta",
- "cyan", "sienna", "orange", "coral"
- };
- char gray_values[Ncolors][30] = {
- "black", "white", "white", "gray50", "gray50",
- "gray100", "gray60", "gray80", "gray40",
- "gray90", "gray50", "gray70", "gray30"
- };
-
- void
- pr_color()
- {
- unsigned long black = BlackPixel(dpy, scr), white = WhitePixel(dpy, scr);
- char option[20], color[30], *v, *ctype;
- XColor xcolor;
- Colormap cmap;
- double intensity = -1;
- int n;
-
- pr_GetR(db, ".mono") && On(value.addr) && Mono++;
- pr_GetR(db, ".gray") && On(value.addr) && Gray++;
- pr_GetR(db, ".reverseVideo") && On(value.addr) && Rv++;
-
- if (!Gray && (vis->class == GrayScale || vis->class == StaticGray))
- Mono++;
-
- if (!Mono) {
- cmap = DefaultColormap(dpy, scr);
- ctype = (Gray) ? "Gray" : "Color";
-
- for (n = 0; n < Ncolors; n++) {
- strcpy(option, ".");
- strcat(option, color_keys[n]);
- (n > 1) && strcat(option, ctype);
- v = pr_GetR(db, option)
- ? (char *) value.addr
- : ((Gray) ? gray_values[n] : color_values[n]);
-
- if (sscanf(v, "%30[^,],%lf", color, &intensity) == 2) {
- if (intensity < 0 || intensity > 1) {
- fprintf(stderr, "\ngnuplot: invalid color intensity in '%s'\n",
- color);
- intensity = 1;
- }
- } else {
- strcpy(color, v);
- intensity = 1;
- }
-
- if (!XParseColor(dpy, cmap, color, &xcolor)) {
- fprintf(stderr, "\ngnuplot: unable to parse '%s'. Using black.\n",
- color);
- colors[n] = black;
- } else {
- xcolor.red *= intensity;
- xcolor.green *= intensity;
- xcolor.blue *= intensity;
- if (XAllocColor(dpy, cmap, &xcolor)) {
- colors[n] = xcolor.pixel;
- } else {
- fprintf(stderr, "\ngnuplot: can't allocate '%s'. Using black.\n",
- v);
- colors[n] = black;
- }
- }
- }
- } else {
- colors[0] = (Rv) ? black : white;
- for (n = 1; n < Ncolors; n++)
- colors[n] = (Rv) ? white : black;
- }
- }
-
- /*-----------------------------------------------------------------------------
- * pr_dashes - determine line dash styles
- *---------------------------------------------------------------------------*/
-
- char dash_keys[Ndashes][10] = {
- "border", "axis",
- "line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8"
- };
-
- char dash_mono[Ndashes][10] = {
- "0", "16",
- "0", "42", "13", "44", "15", "4441", "42", "13"
- };
-
- char dash_color[Ndashes][10] = {
- "0", "16",
- "0", "0", "0", "0", "0", "0", "0", "0"
- };
-
- void
- pr_dashes()
- {
- int n, j, l, ok;
- char option[20], *v;
-
- for (n = 0; n < Ndashes; n++) {
- strcpy(option, ".");
- strcat(option, dash_keys[n]);
- strcat(option, "Dashes");
- v = pr_GetR(db, option)
- ? (char *) value.addr
- : ((Mono) ? dash_mono[n] : dash_color[n]);
- l = strlen(v);
- if (l == 1 && *v == '0') {
- dashes[n][0] = (unsigned char) 0;
- continue;
- }
- for (ok = 0, j = 0; j < l; j++) {
- v[j] >= '1' && v[j] <= '9' && ok++;
- }
- if (ok != l || (ok != 2 && ok != 4)) {
- fprintf(stderr, "gnuplot: illegal dashes value %s:%s\n", option, v);
- dashes[n][0] = (unsigned char) 0;
- continue;
- }
- for (j = 0; j < l; j++) {
- dashes[n][j] = (unsigned char) (v[j] - '0');
- }
- dashes[n][l] = (unsigned char) 0;
- }
- }
-
- /*-----------------------------------------------------------------------------
- * pr_font - determine font
- *---------------------------------------------------------------------------*/
-
- void
- pr_font()
- {
- char *fontname = pr_GetR(db, ".font");
-
- if (!fontname)
- fontname = FallbackFont;
- font = XLoadQueryFont(dpy, fontname);
- if (!font) {
- fprintf(stderr, "\ngnuplot: can't load font '%s'\n", fontname);
- fprintf(stderr, "gnuplot: using font '%s' instead.\n", FallbackFont);
- font = XLoadQueryFont(dpy, FallbackFont);
- if (!font) {
- fprintf(stderr, "\
- gnuplot: can't load font '%s'\n\
- gnuplot: no useable font - X11 aborted.\n", FallbackFont);
- EXIT(1);
- }
- }
- vchar = font->ascent + font->descent;
- }
-
- /*-----------------------------------------------------------------------------
- * pr_geometry - determine window geometry
- *---------------------------------------------------------------------------*/
-
- void
- pr_geometry()
- {
- char *geometry = pr_GetR(db, ".geometry");
- int x, y, flags;
- unsigned int w, h;
-
- if (geometry) {
- flags = XParseGeometry(geometry, &x, &y, &w, &h);
- if (flags & WidthValue)
- gW = w;
- if (flags & HeightValue)
- gH = h;
- if (flags & (WidthValue | HeightValue))
- gFlags = (gFlags & ~PSize) | USSize;
-
- if (flags & XValue)
- gX = (flags & XNegative) ? x + DisplayWidth(dpy, scr) - gW - BorderWidth * 2 : x;
-
- if (flags & YValue)
- gY = (flags & YNegative) ? y + DisplayHeight(dpy, scr) - gH - BorderWidth * 2 : y;
-
- if (flags & (XValue | YValue))
- gFlags = (gFlags & ~PPosition) | USPosition;
- }
- }
-
- /*-----------------------------------------------------------------------------
- * pr_pointsize - determine size of points for 'points' plotting style
- *---------------------------------------------------------------------------*/
-
- void
- pr_pointsize()
- {
- if (pr_GetR(db, ".pointsize")) {
- if (sscanf((char *) value.addr, "%lf", &pointsize) == 1) {
- if (pointsize <= 0 || pointsize > 10) {
- fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", value.addr);
- pointsize = 1;
- }
- } else {
- fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", value.addr);
- pointsize = 1;
- }
- } else {
- pointsize = 1;
- }
- }
-
- /*-----------------------------------------------------------------------------
- * pr_width - determine line width values
- *---------------------------------------------------------------------------*/
-
- char width_keys[Nwidths][30] = {
- "border", "axis",
- "line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8"
- };
-
- void
- pr_width()
- {
- int n;
- char option[20], *v;
-
- for (n = 0; n < Nwidths; n++) {
- strcpy(option, ".");
- strcat(option, width_keys[n]);
- strcat(option, "Width");
- if ((v = pr_GetR(db, option)) != NULL) {
- if (*v < '0' || *v > '4' || strlen(v) > 1)
- fprintf(stderr, "gnuplot: illegal width value %s:%s\n", option, v);
- else
- widths[n] = (unsigned int) atoi(v);
- }
- }
- }
-
- /*-----------------------------------------------------------------------------
- * pr_window - create window
- *---------------------------------------------------------------------------*/
-
- Window
- pr_window(flags, x, y, width, height)
- unsigned int flags;
- int x, y;
- unsigned int width, height;
- {
- char *title = pr_GetR(db, ".title");
- static XSizeHints hints;
- int Tvtwm = 0;
-
- Window win = XCreateSimpleWindow(dpy, root, x, y, width, height, BorderWidth,
- colors[1], colors[0]);
-
- /* ask ICCCM-compliant window manager to tell us when close window
- * has been chosen, rather than just killing us
- */
-
- XChangeProperty(dpy, win, WM_PROTOCOLS, XA_ATOM, 32, PropModeReplace,
- (unsigned char *) &WM_DELETE_WINDOW, 1);
-
- pr_GetR(db, ".clear") && On(value.addr) && Clear++;
- pr_GetR(db, ".tvtwm") && On(value.addr) && Tvtwm++;
-
- if (!Tvtwm) {
- hints.flags = flags;
- } else {
- hints.flags = (flags & ~USPosition) | PPosition; /* ? */
- }
- hints.x = gX;
- hints.y = gY;
- hints.width = width;
- hints.height = height;
-
- XSetNormalHints(dpy, win, &hints);
-
- if (pr_GetR(db, ".iconic") && On(value.addr)) {
- XWMHints wmh;
-
- wmh.flags = StateHint;
- wmh.initial_state = IconicState;
- XSetWMHints(dpy, win, &wmh);
- }
- XStoreName(dpy, win, ((title) ? title : Class));
-
- XSelectInput(dpy, win, KeyPressMask | StructureNotifyMask);
- XMapWindow(dpy, win);
-
- return win;
- }
-
-
- /***** pr_raise ***/
- void
- pr_raise()
- {
- if (pr_GetR(db, ".raise"))
- do_raise = (On(value.addr));
- }
-
-
- void
- pr_persist()
- {
- if (pr_GetR(db, ".persist"))
- persist = (On(value.addr));
- }
-
- /************ code to handle selection export *********************/
-
- #ifdef EXPORT_SELECTION
-
- /* bit of a bodge, but ... */
- static struct plot_struct *exported_plot;
-
- void
- export_graph(plot)
- struct plot_struct *plot;
- {
- FPRINTF((stderr, "export_graph(0x%x)\n", plot));
-
- XSetSelectionOwner(dpy, EXPORT_SELECTION, plot->window, CurrentTime);
- /* to check we have selection, we would have to do a
- * GetSelectionOwner(), but if it failed, it failed - no big deal
- */
- exported_plot = plot;
- }
-
- void
- handle_selection_event(event)
- XEvent *event;
- {
- switch (event->type) {
- case SelectionRequest:
- {
- XEvent reply;
-
- static Atom XA_TARGETS = (Atom) 0;
- if (XA_TARGETS == 0)
- XA_TARGETS = XInternAtom(dpy, "TARGETS", False);
-
- reply.type = SelectionNotify;
- reply.xselection.send_event = True;
- reply.xselection.display = event->xselectionrequest.display;
- reply.xselection.requestor = event->xselectionrequest.requestor;
- reply.xselection.selection = event->xselectionrequest.selection;
- reply.xselection.target = event->xselectionrequest.target;
- reply.xselection.property = event->xselectionrequest.property;
- reply.xselection.time = event->xselectionrequest.time;
-
- FPRINTF((stderr, "selection request\n"));
-
- if (reply.xselection.target == XA_TARGETS) {
- static Atom targets[] = { XA_PIXMAP, XA_COLORMAP };
-
- FPRINTF((stderr, "Targets request from %d\n", reply.xselection.requestor));
-
- XChangeProperty(dpy, reply.xselection.requestor,
- reply.xselection.property, reply.xselection.target, 32, PropModeReplace,
- (unsigned char *) targets, 2);
- } else if (reply.xselection.target == XA_COLORMAP) {
- Colormap cmap = DefaultColormap(dpy, 0);
-
- FPRINTF((stderr, "colormap request from %d\n", reply.xselection.requestor));
-
- XChangeProperty(dpy, reply.xselection.requestor,
- reply.xselection.property, reply.xselection.target, 32, PropModeReplace,
- (unsigned char *) &cmap, 1);
- } else if (reply.xselection.target == XA_PIXMAP) {
-
- FPRINTF((stderr, "pixmap request from %d\n", reply.xselection.requestor));
-
- XChangeProperty(dpy, reply.xselection.requestor,
- reply.xselection.property, reply.xselection.target, 32, PropModeReplace,
- (unsigned char *) &(exported_plot->pixmap), 1);
- } else {
- reply.xselection.property = None;
- }
-
- XSendEvent(dpy, reply.xselection.requestor, False, 0L, &reply);
- /* we never block on XNextEvent(), so must flush manually
- * (took me *ages* to find this out !)
- */
-
- XFlush(dpy);
- }
- break;
- }
- }
-
- #endif /* EXPORT_SELECTION */
-